﻿using Treca.Base_SysManage.Entity;
using Treca.Business.Base_SysManage;
using Treca.Message.Business;
using Treca.Message.Entity;
using Treca.Util;
using Treca.Util.PublishSubscribe;
using EFCore.Sharding;
using LinqKit;
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace Treca.Message
{
    public class PushMessageEvent : IEventHandler<base_message>
    {
        public static string READ = "1";
        public static string UNREAD = "0";


        public static string NORMAL = "0";
        public static string VOICE = "1";

        public AjaxResult Run(string Command, base_message T)
        {
            RunMessage(Command, T);
            return AjaxHelper.Success();
        }
        public AjaxResult RunMessage(string Command, base_message message)
        {
            if (Command == "PushMessage")
            {
                List<string> users = new List<string>();
                List<base_user_message> messages = new List<base_user_message>();
                IRepository service = AutofacHelper.GetScopeService<IRepository>();
                IHubContext<MessageHub> hub = AutofacHelper.GetService<IHubContext<MessageHub>>();
                var s = MessageHub.OnlineUser;
                if (message.IsNullOrEmpty()) return AjaxHelper.Error();
                message.Id = IdHelper.GetId();
                switch (message.Type)
                {
                    case "0":
                        if (!message.RecvUserId.IsNullOrEmpty())
                        {
                            List<string> userlist0 = message.RecvUserId.Split(',').Distinct().ToList();
                            users.AddRange(userlist0);
                            foreach (var user in userlist0)
                            {
                                base_user_message user_Message = new base_user_message();
                                user_Message.Id = IdHelper.GetId();
                                user_Message.UserId = user;
                                user_Message.MessageId = message.Id;
                                user_Message.Title = message.Title;
                                messages.Add(user_Message);
                            }
                        }
                        break;
                    case "1":
                        if (!message.RecvUserId.IsNullOrEmpty())
                        {
                            List<string> rolelist = message.RecvUserId.Split(',').ToList();
                            IBase_UserBusiness base_UserBusiness1 = AutofacHelper.GetScopeService<IBase_UserBusiness>();
                            List<string> userlist1 = base_UserBusiness1.GetIQueryable<Base_UserRoleMap>().Where(t => rolelist.Contains(t.RoleId)).Select(t => t.UserId).Distinct().ToList();
                            users.AddRange(userlist1);
                            foreach (var user in userlist1)
                            {
                                base_user_message user_Message = new base_user_message();
                                user_Message.Id = IdHelper.GetId();
                                user_Message.UserId = user;
                                user_Message.MessageId = message.Id;
                                user_Message.Title = message.Title;
                                messages.Add(user_Message);
                            }
                        }
                        break;
                    case "2":
                        IBase_UserBusiness base_UserBusiness2 = AutofacHelper.GetScopeService<IBase_UserBusiness>();
                        List<string> userlist2 = base_UserBusiness2.GetIQueryable<Base_UserRoleMap>().Select(t => t.UserId).Distinct().ToList();
                        users.AddRange(userlist2);
                        foreach (var user in userlist2)
                        {
                            base_user_message user_Message = new base_user_message();
                            user_Message.Id = IdHelper.GetId();
                            user_Message.UserId = user;
                            user_Message.MessageId = message.Id;
                            user_Message.Title = message.Title;
                            messages.Add(user_Message);
                        }
                        break;
                }
                var res = service.RunTransaction(() =>
                {
                    Ibase_messageBusiness messageBusiness = AutofacHelper.GetScopeService<Ibase_messageBusiness>();
                    messageBusiness.AddData(message);
                    Ibase_user_messageBusiness usermessageBusiness = AutofacHelper.GetScopeService<Ibase_user_messageBusiness>();
                    usermessageBusiness.AddData(messages);
                });
                if (!res.Success)
                { throw res.ex; }
                else
                {
                    if (users.Count > 0)
                        users.Distinct().ForEach((item) =>
                        {
                            var clientsId = s.Where(t => t.UserID == item).Select(t => t.ConnectionId).ToList();
                            var user_message = (from usermsg in service.GetIQueryable<base_user_message>().AsExpandable()
                                                join msg in service.GetIQueryable<base_message>() on usermsg.MessageId equals msg.Id
                                                where msg.Id == message.Id
                                                select msg).FirstOrDefault();
                            if (user_message.MessageType == VOICE)
                            {
                                user_message.Src = "/Message/base_message/TTS?text=" + user_message.Message;
                                hub.Clients.Clients(clientsId).SendAsync("VoiceMessageInfo_" + item, new { Data = user_message });
                            }
                            else
                            {
                                hub.Clients.Clients(clientsId).SendAsync("NewMessageInfo_" + item, new { Data = user_message });
                            }
                            SdkPubSubCenter.PublishCustom("FlashMessage", item);
                        });
                }
            }
            return AjaxHelper.Success();
        }
        public Task<AjaxResult> RunAsync(string Command, base_message T)
        {
            JobHelper.SetIntervalJob(() =>
            {
                RunMessage(Command, T);
            }, TimeSpan.Zero, TimeSpan.Zero);
            return null;
        }
    }
}
